﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace WindowsGameLibrary1
{
    public class AnimationPlayer
    {
        private Animation currentAnimation;
        private Dictionary<AnimationPlayerEnum, Animation> animationSet;
        private double currentTime;
        private int frameCount;        
        private Vector2 scale;
        private Rectangle surceRectangle;
        private Color color;
        private StatusEnum status;
        private float rotate;
        private AnimationPlayerEnum currentAnimationName;
        private SpriteEffects spriteEffects;

        

        private Rectangle rectangle;

        
        private ModeEnum mode;

        // Delegate (Puntero a función) usado para dar efectos de colores sobre los sprite
        private ColorFunction colorFunction;

        public ColorFunction ColorFunction
        {
            get { return colorFunction; }
            set { colorFunction = value; }
        }

        public SpriteEffects SpriteEffects
        {
            get { return spriteEffects; }
            set { spriteEffects = value; }
        }
        public AnimationPlayerEnum CurrentAnimationName
        {
            get { return currentAnimationName; }
            set { currentAnimationName = value; }
        }

        public Rectangle Rectangle
        {
            get { return rectangle; }
            set { rectangle = value; }
        }
        public float Rotate
        {
            get { return rotate; }
            set { rotate = value; }
        }
        




        public Vector2 Scale
        {
            get { return scale; }
            set { scale = value; }
        }

        public ModeEnum Mode
        {
            get { return mode; }
            set { mode = value; }
        }

        public AnimationPlayer()
        {
            currentAnimation = new Animation();
            animationSet = new Dictionary<AnimationPlayerEnum, Animation>();
            currentTime = 0;
            frameCount = 0;
            scale = Vector2.One;
            color = Color.White;
            status = StatusEnum.Stop;
            rotate = 0;
            rectangle = Rectangle.Empty;
            mode = ModeEnum.Ever;
            currentAnimationName = AnimationPlayerEnum.NONE;
            colorFunction = null;
            surceRectangle = Rectangle.Empty;
            spriteEffects = SpriteEffects.None;

        }
        public void CalcAnimationTime()
        {
            currentAnimation.CalcAnimationTime();
        }
        public float GiveAnimationTime()
        {
            return currentAnimation.AnimationTime;
        }
        public void setAnimationTime(int time)
        {
            currentAnimation.AnimationTime = time;
        }

        public void ChangeAnimation(AnimationPlayerEnum animation, ModeEnum Mode)
        {
            if (!currentAnimationName.Equals(animation))
            {
                currentAnimation = animationSet[animation];
                currentTime = 0;
                frameCount = 0;
                currentAnimationName = animation;
                mode = Mode;
            }
        }

        public void AddAnimation(AnimationPlayerEnum key, Animation animation)
        {
            animationSet.Add(key, animation);
        }

        public void RemAnimation(AnimationPlayerEnum key)
        {
            animationSet.Remove(key);
        }

        public void Draw(SpriteBatch spriteBatch, GameTime gameTime, Vector2 ownerPosition, float order)
        {
            Vector2 Origin = Vector2.Zero;
            if (spriteEffects.Equals(SpriteEffects.None))
            {   
                Origin=currentAnimation.getFrame(frameCount).Origin;
            }
            else
            {
                if (spriteEffects.Equals(SpriteEffects.FlipHorizontally))
	            {
		            Origin=currentAnimation.getFrame(frameCount).FlipOrigin;
	            }
                
            }
            if (colorFunction != null)
                color = colorFunction(color, gameTime);
            if(surceRectangle.Equals(Rectangle.Empty))
                spriteBatch.Draw(currentAnimation.getFrame(frameCount).Sprite, ownerPosition, null, color, MathHelper.ToRadians(rotate), Origin, scale, spriteEffects, order);
            else
                spriteBatch.Draw(currentAnimation.getFrame(frameCount).Sprite, ownerPosition, surceRectangle, color, MathHelper.ToRadians(rotate), Origin, scale, spriteEffects, order);
        }

        public void update(GameTime gameTime)
        {
            if (status.Equals(StatusEnum.Play))
            {
                currentTime += gameTime.ElapsedGameTime.TotalSeconds;
                if (currentTime > currentAnimation.getFrame(frameCount).Duration)
                {
                    FrameCountUpDate();
                    currentTime = 0;
                }

            }
            else
            {
                if (status.Equals(StatusEnum.Stop))
                {
                    frameCount = 0;
                }

            }

        }

        public void Play()
        {
            status = StatusEnum.Play;
        }

        public void Stop()
        {
            status = StatusEnum.Stop;
        }

        public void Pause()
        {
            status = StatusEnum.Pause;
        }

        private void FrameCountUpDate()
        {
            if (frameCount + 1 < currentAnimation.SpriteCount)
            {
                frameCount++;

            }
            else
            {
                if (mode.Equals(ModeEnum.One))
                {
                    status = StatusEnum.Pause;
                }
                else
                {
                    frameCount = 0;
                }

            }
        }

        public Vector2 ImageSize()
        {
            return new Vector2(currentAnimation.getFrame(frameCount).Sprite.Width, currentAnimation.getFrame(frameCount).Sprite.Height);
        }

        public CollisionCoordinates GiveCollisionRectangle() 
        {
            if (spriteEffects.Equals(SpriteEffects.None))
            {
                return currentAnimation.getFrame(frameCount).CollisionObject.Rectangle;
            }
            else
            {
                return currentAnimation.getFrame(frameCount).FlipCollisionObject.Rectangle;
            }
        }


        public List<CollisionCoordinates> GiveCollisionRectangles()
        {
            if (spriteEffects.Equals(SpriteEffects.None))
            {
                return currentAnimation.getFrame(frameCount).CollisionObject.Rectangles;
            }
            else
            {
                return currentAnimation.getFrame(frameCount).FlipCollisionObject.Rectangles;
            }
        }

    }

    public enum StatusEnum
    {
        Play,
        Stop,
        Pause
    }
    public enum ModeEnum
    {
        One,
        Ever
    }

    

    public enum AnimationPlayerEnum
    {
        NONE,
        PARADO,
        AGACHADO,
        CAMINANDO,
        ATACANDO,
        MUERTO,
        BACKGROUND
        
    }

    
}
